package cn.exlu.coco.core.utils;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;

/**
 * 二位码生成工具类
 * @author 汪翔
 *
 */
public class QrcodeUtil {
    /** 二维码图片宽带 */
    private static int WIDTH = 200;
    /** 二维码图片高度 */
    private static int HEIGHT = 200;
    
    private static int FONT_SIZE = 16;
    
    /** 二维码其他特性设置 */
    private static Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
    static{
        // 设置二维码白边边距
        hints.put(EncodeHintType.MARGIN, 0);
    }
    
    public static OutputStream qrcode_text(OutputStream os, String content, String pressText, Integer sFontSize, Integer sWidth, Integer sHeight, Map<EncodeHintType, Object> sHints) throws IOException{

        if(sWidth == null){
            sWidth = WIDTH;
        }
        
        if(sHeight == null){
            sHeight = HEIGHT;
        }
        
        if(sFontSize == null){
            sFontSize = FONT_SIZE;
        }
        
        if(sHints == null){
            sHints = hints;
        }
        
        //计算文字开始的位置
        //x开始的位置：（图片宽度-字体大小*字的个数）/2
        int startX = Math.abs((sWidth - (sFontSize * pressText.length())) / 2);
        //y开始的位置：图片高度-（图片高度-图片宽度）/2
        int startY = sHeight;
        
        int bottomHeight = sFontSize + 4;
        
        
        try {

            QRCodeWriter writer = new QRCodeWriter();
            BitMatrix m = writer.encode(content, BarcodeFormat.QR_CODE, sWidth, sHeight, sHints);
            // 定义图片总高度
            BufferedImage image = new BufferedImage(sWidth, sHeight + bottomHeight+4,BufferedImage.TYPE_INT_RGB);
            BufferedImage qrcodeImage = MatrixToImageWriter.toBufferedImage(m);
            Graphics g = image.createGraphics();
            // 画二维码区域图片
            g.drawImage(qrcodeImage, 0, 0, sWidth, sHeight, null);
            g.setColor(Color.WHITE);
            g.setFont(new Font(null, Font.BOLD, sFontSize));
            g.fillRect(0, startY, sWidth, bottomHeight+4);

            g.setColor(Color.BLACK);
            g.drawString(pressText, startX, startY + bottomHeight); // 画文字时，起点是从文字底线计算的。
            g.dispose();
            
            ImageIO.write(image, "png", os);

        } catch (WriterException e) {

        } finally {
           
        }

        return null;
    }

    
    /**
     * 解析二维码内容
     * @param is
     * @return
     */
    public static String decode(InputStream is){
        BufferedImage image;  
        try {
            image = ImageIO.read(is);
            LuminanceSource source = new BufferedImageLuminanceSource(image);  
            Binarizer binarizer = new HybridBinarizer(source);  
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);  
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();  
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");  
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码  
            return result.getText();
        } catch (IOException e) {  
            return null;
        } catch (NotFoundException e) {  
            return null;
        }  
    }


}
